#include <iostream>
#include <memory>
#include "Ioc.h"
using namespace std;

class Cal
{
public:
    Cal()
    {
    }
    Cal(double a, double b) : m_a(a), m_b(b)
    {
    }
    virtual double get_result() = 0;
    double m_a;
    double m_b;
};

class Add : public Cal
{
public:
    Add()
    {
    }
    Add(double a, double b) : Cal(a, b)
    {
    }

    virtual double get_result() override
    {
        return m_a + m_b;
    }
};

class Sub : public Cal
{
public:
    Sub()
    {
    }
    Sub(double a, double b) : Cal(a, b)
    {
    }

    virtual double get_result() override
    {
        return m_a - m_b;
    }
};

class Mul : public Cal
{
public:
    Mul()
    {
    }

    Mul(double a, double b) : Cal(a, b)
    {
    }

    virtual double get_result() override
    {
        return m_a * m_b;
    }
};

class Div : public Cal
{
public:
    Div()
    {
    }

    Div(double a, double b) : Cal(a, b)
    {
    }

    virtual double get_result() override
    {
        return m_a / m_b;
    }
};
//class Log；
// 工厂模式
class Factory
{
public:
    virtual Cal *createoperator() = 0;
};

class AddFactory : public Factory
{
public:
    virtual Cal *createoperator()
    {
        return new Add;
    }
};

class SubFactory : public Factory
{
public:
    virtual Cal *createoperator()
    {
        return new Sub;
    }
};

class MulFactory : public Factory
{
public:
    virtual Cal *createoperator()
    {
        return new Mul;
    }
};

class DivFactory : public Factory
{
public:
    virtual Cal *createoperator()
    {
        return new Div;
    }
};


// 简单工厂：隐藏类实例化对象的过程，实现new和类名解耦
// 缺点：违背了开闭原则
class OperationFactory
{
public:
    static Cal *creatoperation(string op)
    {
        Cal *cal;

        if (op == "+")
        {
            cal = new Add;
        }
        else if (op == "-")
        {
            cal = new Sub;
        }
        else if (op == "*")
        {
            cal = new Mul;
        }
        else if (op == "/")
        {
            //
        }
    }
};

//简单工厂 + 工厂模式
class CalFactory
{
public:
    static Factory *createFactory(string op)
    {
        Factory *factory;
        if (op == "+")
        {
            factory = new AddFactory;
        }
        else if (op == "-")
        {
            factory = new SubFactory;
        }
        else if (op == "/")
        {
            factory = new DivFactory;
        }

        return factory;
    }
};

int main(int argc, char **argv)
{
    double a;
    double b;
    string op;

    cin >> a;
    cin >> b;
    cin >> op;

    shared_ptr<int> s(new int(5));
#if 0 
    shared_ptr<int> p = std::make_shared<int>(5);
    pair<int,bool> p2 = std::make_pair<int,bool>(5,true);
    
    Cal *cal = OperationFactory::creatoperation(op);
#endif
    //"Add"
    string class_name;
    cin >> class_name;
    //"Add" -- Add add
    //Cal *cal = create(class_name);
    
    Cal *cal;
    Factory *factory = CalFactory::createFactory(op);
    cal = factory->createoperator();

    cal->m_a = a;
    cal->m_b = b;
    cout << cal->get_result() << endl;

    return 0;
}
